package com.honghe.system.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.honghe.common.utils.DateUtils;
import com.honghe.common.utils.SecurityUtils;
import com.honghe.system.domain.SysAttendance;
import com.honghe.system.domain.vo.AttendanceStatsVO;
import com.honghe.system.domain.vo.AttendanceChartVO;
import com.honghe.system.mapper.SysAttendanceMapper;
import com.honghe.system.service.ISysAttendanceService;

/**
 * 员工打卡记录Service业务层处理
 * 
 * @author honghe
 */
@Service
public class SysAttendanceServiceImpl implements ISysAttendanceService 
{
    @Autowired
    private SysAttendanceMapper sysAttendanceMapper;

    /**
     * 查询员工打卡记录
     * 
     * @param attendanceId 员工打卡记录主键
     * @return 员工打卡记录
     */
    @Override
    public SysAttendance selectSysAttendanceByAttendanceId(Long attendanceId)
    {
        return sysAttendanceMapper.selectSysAttendanceByAttendanceId(attendanceId);
    }

    /**
     * 查询员工打卡记录列表
     * 
     * @param sysAttendance 员工打卡记录
     * @return 员工打卡记录
     */
    @Override
    public List<SysAttendance> selectSysAttendanceList(SysAttendance sysAttendance)
    {
        return sysAttendanceMapper.selectSysAttendanceList(sysAttendance);
    }
    
    /**
     * 查询今日打卡记录
     * 
     * @param userId 用户ID
     * @return 员工打卡记录
     */
    @Override
    public SysAttendance selectTodayAttendance(Long userId)
    {
        // 如果没有提供用户ID，则使用当前登录用户的ID
        if (userId == null) {
            userId = SecurityUtils.getUserId();
        }
        Date today = DateUtils.getNowDate();
        return sysAttendanceMapper.selectTodayAttendance(userId, today);
    }
    
    /**
     * 查询打卡统计数据
     * 
     * @param sysAttendance 员工打卡记录
     * @return 打卡统计数据
     */
    @Override
    public AttendanceStatsVO selectAttendanceStats(SysAttendance sysAttendance)
    {
        return sysAttendanceMapper.selectAttendanceStats(sysAttendance);
    }
    
    /**
     * 查询打卡图表数据
     * 
     * @param params 查询参数
     * @return 打卡图表数据
     */
    @Override
    public AttendanceChartVO selectAttendanceChartData(Map<String, Object> params)
    {
        AttendanceChartVO chartVO = new AttendanceChartVO();
        
        // 获取时间类型（周/月）
        String timeType = (String) params.get("timeType");
        if (timeType == null || timeType.isEmpty())
        {
            timeType = "week"; // 默认为周
        }
        
        // 生成日期范围
        List<String> dateList = new ArrayList<>();
        List<Date> rawDates = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        
        // 如果没有指定开始日期和结束日期，则根据时间类型生成
        if (params.get("beginTime") == null || params.get("endTime") == null)
        {
            if ("week".equals(timeType))
            {
                // 获取本周的日期范围
                calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                for (int i = 0; i < 7; i++)
                {
                    Date date = calendar.getTime();
                    rawDates.add(date);
                    dateList.add(dateFormat.format(date));
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                }
            }
            else if ("month".equals(timeType))
            {
                // 获取本月的日期范围
                calendar.set(Calendar.DAY_OF_MONTH, 1);
                int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
                for (int i = 0; i < daysInMonth; i++)
                {
                    Date date = calendar.getTime();
                    rawDates.add(date);
                    dateList.add(dateFormat.format(date));
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                }
            }
        }
        else
        {
            // 使用指定的日期范围
            try
            {
                Date beginDate = dateFormat.parse((String) params.get("beginTime"));
                Date endDate = dateFormat.parse((String) params.get("endTime"));
                calendar.setTime(beginDate);
                
                while (!calendar.getTime().after(endDate))
                {
                    Date date = calendar.getTime();
                    rawDates.add(date);
                    dateList.add(dateFormat.format(date));
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                }
            }
            catch (Exception e)
            {
                // 日期解析异常，使用默认处理
                calendar = Calendar.getInstance();
                calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
                for (int i = 0; i < 7; i++)
                {
                    Date date = calendar.getTime();
                    rawDates.add(date);
                    dateList.add(dateFormat.format(date));
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                }
            }
        }
        
        // 设置日期列表
        chartVO.setDates(dateList);
        
        // 查询打卡数据
        // 如果不是管理员，只能查询自己的打卡记录
        if (!SecurityUtils.isAdmin(SecurityUtils.getUserId()) && params.get("userId") == null)
        {
            params.put("userId", SecurityUtils.getUserId());
        }
        
        // 添加日期范围参数
        params.put("beginDate", dateList.get(0));
        params.put("endDate", dateList.get(dateList.size() - 1));
        
        // 查询打卡记录
        List<Map<String, Object>> attendanceData = sysAttendanceMapper.selectAttendanceChartData(params);
        
        // 初始化数据
        List<Integer> normalList = new ArrayList<>();
        List<Integer> lateList = new ArrayList<>();
        List<Integer> earlyList = new ArrayList<>();
        List<Integer> absentList = new ArrayList<>();
        
        // 将查询结果转换为图表数据格式
        Map<String, Map<String, Integer>> dataMap = new HashMap<>();
        for (Map<String, Object> data : attendanceData)
        {
            String dateStr = (String) data.get("attendanceDate");
            String status = (String) data.get("status");
            Integer isLate = 0;
            Integer isEarly = 0;
            
            // 安全地将数据库返回的可能是Long类型的值转换为Integer
            if (data.get("isLate") != null) {
                if (data.get("isLate") instanceof Long) {
                    isLate = ((Long) data.get("isLate")).intValue();
                } else if (data.get("isLate") instanceof Integer) {
                    isLate = (Integer) data.get("isLate");
                }
            }
            
            if (data.get("isEarly") != null) {
                if (data.get("isEarly") instanceof Long) {
                    isEarly = ((Long) data.get("isEarly")).intValue();
                } else if (data.get("isEarly") instanceof Integer) {
                    isEarly = (Integer) data.get("isEarly");
                }
            }
            
            if (!dataMap.containsKey(dateStr))
            {
                dataMap.put(dateStr, new HashMap<>());
                dataMap.get(dateStr).put("normal", 0);
                dataMap.get(dateStr).put("late", 0);
                dataMap.get(dateStr).put("early", 0);
                dataMap.get(dateStr).put("absent", 0);
            }
            
            if ("0".equals(status))
            {
                // 正常
                if (isLate != null && isLate == 1)
                {
                    dataMap.get(dateStr).put("late", dataMap.get(dateStr).get("late") + 1);
                }
                else if (isEarly != null && isEarly == 1)
                {
                    dataMap.get(dateStr).put("early", dataMap.get(dateStr).get("early") + 1);
                }
                else
                {
                    dataMap.get(dateStr).put("normal", dataMap.get(dateStr).get("normal") + 1);
                }
            }
            else
            {
                // 异常
                dataMap.get(dateStr).put("absent", dataMap.get(dateStr).get("absent") + 1);
            }
        }
        
        // 填充每一天的数据
        for (String dateStr : dateList)
        {
            if (dataMap.containsKey(dateStr))
            {
                normalList.add(dataMap.get(dateStr).get("normal"));
                lateList.add(dataMap.get(dateStr).get("late"));
                earlyList.add(dataMap.get(dateStr).get("early"));
                absentList.add(dataMap.get(dateStr).get("absent"));
            }
            else
            {
                normalList.add(0);
                lateList.add(0);
                earlyList.add(0);
                absentList.add(1); // 默认为缺勤
            }
        }
        
        chartVO.setNormal(normalList);
        chartVO.setLate(lateList);
        chartVO.setEarly(earlyList);
        chartVO.setAbsent(absentList);
        
        return chartVO;
    }

    /**
     * 新增员工打卡记录
     * 
     * @param sysAttendance 员工打卡记录
     * @return 结果
     */
    @Override
    public int insertSysAttendance(SysAttendance sysAttendance)
    {
        sysAttendance.setCreateTime(DateUtils.getNowDate());
        return sysAttendanceMapper.insertSysAttendance(sysAttendance);
    }
    
    /**
     * 用户签到
     * 
     * @param location 签到地点
     * @param remark 备注
     * @return 结果
     */
    @Override
    public int clockIn(String location, String remark)
    {
        // 获取当前用户ID
        Long userId = SecurityUtils.getUserId();
        String userName = SecurityUtils.getUsername();
        Date today = DateUtils.getNowDate();
        
        // 查询今日是否已打卡
        SysAttendance todayAttendance = sysAttendanceMapper.selectTodayAttendance(userId, today);
        
        // 如果今日已有打卡记录，且已签到，则不允许重复签到
        if (todayAttendance != null && todayAttendance.getClockInTime() != null)
        {
            return 0;
        }
        
        // 获取当前时间
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
        String currentTime = timeFormat.format(new Date());
        
        if (todayAttendance == null)
        {
            // 创建新的打卡记录
            SysAttendance attendance = new SysAttendance();
            attendance.setUserId(userId);
            attendance.setAttendanceDate(today);
            attendance.setClockInTime(currentTime);
            attendance.setClockInLocation(location);
            attendance.setRemark(remark);
            attendance.setCreateBy(userName);
            return insertSysAttendance(attendance);
        }
        else
        {
            // 更新今日打卡记录
            todayAttendance.setClockInTime(currentTime);
            todayAttendance.setClockInLocation(location);
            todayAttendance.setRemark(remark);
            todayAttendance.setUpdateBy(userName);
            todayAttendance.setUpdateTime(DateUtils.getNowDate());
            return updateSysAttendance(todayAttendance);
        }
    }
    
    /**
     * 用户签退
     * 
     * @param attendanceId 考勤记录ID
     * @param location 签退地点
     * @param remark 备注
     * @return 结果
     */
    @Override
    public int clockOut(Long attendanceId, String location, String remark)
    {
        // 获取当前用户ID和用户名
        String userName = SecurityUtils.getUsername();
        
        // 如果提供了考勤ID，则直接查询该记录
        SysAttendance attendance = null;
        if (attendanceId != null) {
            attendance = sysAttendanceMapper.selectSysAttendanceByAttendanceId(attendanceId);
            if (attendance == null) {
                return 0; // 找不到记录
            }
        } else {
            // 兼容旧版本，如果没有提供考勤ID，则通过用户ID和日期查询
            Long userId = SecurityUtils.getUserId();
            Date today = DateUtils.getNowDate();
            
            // 查询今日是否已打卡
            attendance = sysAttendanceMapper.selectTodayAttendance(userId, today);
            
            // 如果今日没有打卡记录，或者未签到，则不允许签退
            if (attendance == null || attendance.getClockInTime() == null) {
                return 0;
            }
        }
        
        // 如果已签退，则不允许重复签退
        if (attendance.getClockOutTime() != null) {
            return 0;
        }
        
        // 获取当前时间
        SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
        String currentTime = timeFormat.format(new Date());
        
        // 更新签退信息
        attendance.setClockOutTime(currentTime);
        attendance.setClockOutLocation(location);
        if (remark != null && !remark.isEmpty()) {
            attendance.setRemark(remark);
        }
        attendance.setUpdateBy(userName);
        attendance.setUpdateTime(DateUtils.getNowDate());
        
        return updateSysAttendance(attendance);
    }

    /**
     * 修改员工打卡记录
     * 
     * @param sysAttendance 员工打卡记录
     * @return 结果
     */
    @Override
    public int updateSysAttendance(SysAttendance sysAttendance)
    {
        sysAttendance.setUpdateTime(DateUtils.getNowDate());
        return sysAttendanceMapper.updateSysAttendance(sysAttendance);
    }

    /**
     * 批量删除员工打卡记录
     * 
     * @param attendanceIds 需要删除的员工打卡记录主键
     * @return 结果
     */
    @Override
    public int deleteSysAttendanceByAttendanceIds(Long[] attendanceIds)
    {
        return sysAttendanceMapper.deleteSysAttendanceByAttendanceIds(attendanceIds);
    }

    /**
     * 删除员工打卡记录信息
     * 
     * @param attendanceId 员工打卡记录主键
     * @return 结果
     */
    @Override
    public int deleteSysAttendanceByAttendanceId(Long attendanceId)
    {
        return sysAttendanceMapper.deleteSysAttendanceByAttendanceId(attendanceId);
    }
} 